/* global BufferEncoding */
import * as Minio from 'minio';
import logger from '../../common/logger';
import { Readable } from 'stream';
import { StorageConfig } from './type';
import { ObjectStorage } from './objectStorage';
// @ts-ignore
import { UploadedObjectInfo } from 'minio';
export class MinioStorage implements ObjectStorage {

  private minioClient: Minio.Client;

  constructor(config: StorageConfig) {
    this.minioClient = new Minio.Client({
      endPoint: config.host,
      port: config.port,
      useSSL: config.useSSL,
      accessKey: config.accessKey,
      secretKey: config.accessSecret
    });
  }

  putObject(bucket: string, objectName: string, content: string | Buffer): Promise<UploadedObjectInfo> {
    return this.minioClient.putObject(bucket, objectName, content);
  }
  fPutObject(bucket: string, objectName: string, filePath: string, metadata: any = {}): Promise<UploadedObjectInfo> {
    return this.minioClient.fPutObject(bucket, objectName, filePath, metadata);
  }
  getObject(bucket: string, objectName: string): Promise<Readable> {
    return this.minioClient.getObject(bucket, objectName);
  }

  getString(bucket: string, objectName: string, encoding: BufferEncoding = 'utf8'): Promise<string> {
    return new Promise<string>(async (resolve, reject) => {
      const readStream: Readable = await this.getObject(bucket, objectName);
      readStream.setEncoding(encoding);
      let content = '';
      readStream.on('data', (trunk) => {
        content += trunk;
      });
      readStream.on('error', (error) => {
        logger.error(`read object(bucket=${bucket},objectName=${objectName}) failed`);
        reject(error);
      });
      readStream.on('end', async () => {
        resolve(content);
      });
    });
  }

  fGetObject(bucket: string, objectName: string, filePath: string): Promise<void> {
    return this.minioClient.fGetObject(bucket, objectName, filePath);
  }
  removeObject(bucket: string, objectName: string): Promise<void> {
    return this.minioClient.removeObject(bucket, objectName);
  }
}